using System;
using System.Collections.Generic;
using System.Windows.Forms;
using ClientApi;
using CommonGui.Progress;
using DataModel.Reports;
using RitaReports.Travels;

namespace RitaReports.Expenses
{
    public class ExpensesReport : IRitaReport
    {
        private TravelsReportInitData _initData;
        private readonly string name;
        private readonly ExpensesReport[] subReports = null;
        private readonly IReportViewer viewer;
        private readonly IReportMap map;
        private readonly ExpensesFilter _filter = new ExpensesFilter();
        private ExpensesDataSource _dataSource;

        #region IRitaReport Members

        public IReportMap ReportMap
        {
            get { return map; }
        }

        public string Name
        {
            get { return name; }
        }

        public IReportFilter Filter
        {
            get { return _filter; }
        }

        public IReportViewer Viewer
        {
            get { return viewer; }
        }

        public IReportDataSource DataSource
        {
            get { return _dataSource; }
        }

        public IRitaReport[] SubReports
        {
            get { return subReports; }
        }

        public void UpdateDataSource(IReportFilterConditionds reportFilter, IWin32Window owner)
        {
            List<JobProgressItem> jobs = new List<JobProgressItem>();
            ExpensesFilterConditionds filter = (ExpensesFilterConditionds) reportFilter;
            JobProgressItem job;

            if (_initData == null)
            {
                job = new JobProgressItem("Downloading report...");
                job.ProgressInformator = ReportDataProvider.Instance;
                job.Job = delegate
                              {
                                  _initData = ReportDataProvider.Instance.GetTravelsReportInitData();
                              };
                jobs.Add(job);
            }

            job = new JobProgressItem("Downloading report data...");
            job.ProgressInformator = ReportDataProvider.Instance;
            job.Job = delegate
                          {
                              _dataSource = new ExpensesDataSource(_initData.Organizations,
                                                                   ReportDataProvider.Instance.GetTravelsReportData(
                                                                       filter.OrgId,
                                                                       filter.Seniority,
                                                                       filter.Destination,
                                                                       filter.Date,
                                                                       TravelsReportDelegation.All));
                          };

            jobs.Add(job);

            JobsProgressForm.ShowProgress(jobs, owner);

            if (_initData != null && _filter.Inited == false)
            {
                _filter.Init(_initData);
            }
        }

        #endregion

        public ExpensesReport()
            : this(ExpensesReportType.ByTravels)
        {
        }

        ExpensesReport(ExpensesReportType expensesType)
        {
            switch(expensesType)
            {
                case ExpensesReportType.ByTravels:
                    this.name = "Expenses";
                    this.viewer = new ExpensesByTravelsViewer();
                    this.map = new TravelsMap();
                    subReports = new ExpensesReport[]
                    {
                        new ExpensesReport(ExpensesReportType.ByOrganizations),
                        new ExpensesReport(ExpensesReportType.BySeniority),
                        new ExpensesReport(ExpensesReportType.ByDestination),
                    };
                    break;
                case ExpensesReportType.ByOrganizations:
                    this.name = "By Organization";
                    this.viewer = new ExpensesByOrgViewer();
                    break;
                case ExpensesReportType.BySeniority:
                    this.name = "By Seniority";
                    this.viewer = new ExpensesBySeniorityViewer();
                    break;
                case ExpensesReportType.ByDestination:
                    this.name = "By Destination";
                    this.viewer = new ExpensesByDestinationViewer();
                    break;
                default:
                    throw new ArgumentOutOfRangeException("expensesType");
            }
        }

        enum ExpensesReportType
        {
            ByTravels, ByOrganizations, BySeniority, ByDestination
        }
    }

    
}
